//
// Created by Baymax on 2023/3/1.
//
#ifdef __cplusplus
extern "C" {
#endif
#ifndef AWDB_C_NEW_AWDB_H
#define AWDB_C_NEW_AWDB_H


#include "stdint.h"
#include "stddef.h"
#include <stdio.h>
#include <stdbool.h>
#define BUFFER_SIZE 4000
#ifdef _WIN32

#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib")
#else
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif
#ifdef _MSC_VER
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef _W64 int ssize_t;
#endif
#endif

#define  IPv4  0x01
#define  IPv6  0x02
#define ErrNoErr 0 //No error.
#define ErrDatabaseError 4 //"database error"
#define ErrIPFormat 5 //"Query IP Format error."
#define ErrNoSupportIPv6 8 //"IPv6 not support"
#define ErrDataNotExists 9 //"data is not exists"

//查找索引 
typedef struct AWDB_detail_s {
    const struct AWDB_s *awdb;
    uint32_t offset;
    uint32_t bash_offset;
} AWDB_detail_s;


//结果载体 
typedef struct AIWEN_result {
    bool is_found;
    AWDB_detail_s entry;
    uint16_t netmask;
    int index_offset;
//    char str[5000];

} AIWEN_result;

typedef struct awdb_meta_data {
    int node_count;
    const char *ip_version;
    int byte_len;
    char **columns;
    int columns_length;
    int metadata_len;
    int decode_type;
} awdb_meta_data;

// 列表
typedef struct StringList {
    char *list[100];
    int size;
} StringList;

// awdb结构载体
typedef struct AWDB_s {
    const char *filename;
    int file_size;
    int data_size;
    const uint8_t *file_content;
    uint16_t depth;
    int ls_s;
    const uint8_t *data_section;
    uint32_t data_section_size;
    awdb_meta_data aiwen_metadata;
    StringList list;
} AWDB_s;

//typedef unsigned __int128 uint128_t;


extern int AWDB_file_open(const char *const filename,
                          AWDB_s *const awdb);

extern AIWEN_result AWDB_reader_find(AWDB_s *reader, const char *addr);

extern int AWDB_find0(AWDB_s *reader, AIWEN_result *result, const char *addr);

extern int AWDB_search(AWDB_s *reader, const u_char *ip, int bit_count, unsigned int *node);

extern unsigned int AWDB_read_node(AWDB_s *reader, int node, int index,const uint8_t *search_tree);

extern int AWDB_resolve(FILE *const stream,AWDB_s *reader, AIWEN_result *result);

extern uint32_t resolve( FILE *stream,AWDB_s *reader, AIWEN_result *result, int offset, int deep, int index, const uint8_t *data_section);

extern uint32_t resolve2(FILE *stream,AWDB_s *reader, AIWEN_result *result);

extern char *strreplace(const char *str, const char *old, const char *new_str);

extern char *trim(char *str);

extern StringList str_2_list(const char *str);
extern void AWDB_close(AWDB_s *const awdb);
#endif //AWDB_C_NEW_AWDB_H
#ifdef __cplusplus
}
#endif
